﻿using System;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Collections.Generic;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Web.UI;

namespace VoteList.Layouts.VoteList
{
    public partial class PollRanking : LayoutsPageBase
    {
        public class RankItem : IComparable, IEquatable<RankItem>
        {
            public string AccountName
            {
                get;
                set;
            }
            private SPUser _user;
            public SPUser User
            {
                get
                {
                    if (_user == null&& !string.IsNullOrEmpty(AccountName))
                    {
                        _user= SPContext.Current.Web.EnsureUser(AccountName);
                    }
                    return _user;
                }
                
            }
            private string _userName;
            public string UserName
            {
                get
                {
                    if (string.IsNullOrEmpty(_userName) && User != null)
                    {
                        return User.Name;
                    }
                    return _userName;
                }
                set
                {
                    _userName = value;
                }
            }            
            public string HeadImage
            {
                get
                {
                    if (string.IsNullOrEmpty(AccountName))
                    {
                        return string.Empty;
                    }
                    SPWeb web = SPContext.Current.Site.RootWeb;
                    SPList picList = web.Lists.TryGetList(Define.PICLISTNAME);
                    string loginName = AccountName;
                    int index = loginName.IndexOf('\\');

                    if (index > -1)
                    {
                        loginName = loginName.Substring(index + 1);
                    }

                    if (picList != null)
                    {
                        foreach (SPListItem item in picList.Items)
                        {
                            if (item.Name.Contains(loginName))
                            {
                                return web.Url + "/" + item.Url;
                            }
                        }
                    }

                    return GetRandomDefaultPhotoURL();
                }
            }
            public int Vote
            {
                get;
                set;
            }
            /// <summary>
            /// 0 No
            /// 1 Yes
            /// </summary>
            public int IsCandidate
            {
                get;
                set;
            }
            public DateTime LastVotingTime
            {
                get;
                set;
            }
            public string Location
            {
                get;
                set;
            }
            public RankItem() 
            {
                this.AccountName = string.Empty;
                this.Location = string.Empty;
                this.UserName = string.Empty;                
                this.Vote = 0;
            }
            public RankItem(string accountName)
            {
                this.AccountName = accountName;
            }
            public int CompareTo(object obj)
            {
                RankItem item = obj as RankItem;
                if (item != null)
                {
                    if (this.IsCandidate > item.IsCandidate)
                    {
                        return -1;
                    }
                    if (this.IsCandidate < item.IsCandidate)
                    {
                        return 1;
                    }
                    if (this.Vote > item.Vote)
                    {
                        return -1;
                    }
                    if (this.Vote < item.Vote)
                    {
                        return 1;
                    }
                    if (this.Vote == item.Vote)
                    {
                        if (this.LastVotingTime < item.LastVotingTime)
                        {
                            return -1;
                        }
                        if (this.LastVotingTime > item.LastVotingTime)
                        {
                            return 1;
                        }
                    }
                    return 0;
                }
                throw new ArgumentException("object is not a RankItem");
            }

            public bool Equals(RankItem other)
            {
                if (other != null)
                {
                    if (this.AccountName == other.AccountName)
                    {
                        return true;
                    }
                }
                return false;
            }

            private string GetRandomDefaultPhotoURL()
            {
                Random rnd = new Random();
                int rndNum = rnd.Next(1, 4);
                string strPhotoUrl = string.Empty;
                switch (rndNum)
                {
                    case 1:
                        strPhotoUrl = "/_layouts/VoteList/Images/DefaultImage01.png";
                        break;
                    case 2:
                        strPhotoUrl = "/_layouts/VoteList/Images/DefaultImage02.png";
                        break;
                    case 3:
                        strPhotoUrl = "/_layouts/VoteList/Images/DefaultImage03.png";
                        break;
                    case 4:
                        strPhotoUrl = "/_layouts/VoteList/Images/DefaultImage04.png";
                        break;
                    default:
                        strPhotoUrl = "/_layouts/VoteList/Images/DefaultImage01.png";
                        break;
                }
                return strPhotoUrl;
            }
        }
        private List<RankItem> _pollList = null;
        public List<RankItem> PollList
        {
            get
            {
                if (_pollList == null)
                {                    
                    SPList list = SPContext.Current.Site.RootWeb.Lists[Define.DATALISTNAME];
                    if (list != null)
                    {
                        _pollList = new List<RankItem>();

                        foreach (SPListItem item in list.Items)
                        {
                            try
                            {                                
                                SPUser itemUser = GetUserFieldValue(Define.DATACOLUMN_ACCOUNT, item);
                                if (itemUser != null)
                                {
                                    RankItem rankItem = _pollList.Find(
                                                delegate(RankItem rk)
                                                {
                                                    return rk.AccountName == itemUser.LoginName;
                                                });
                                    //Does not exist in the list, add 
                                    if (rankItem == null)
                                    {
                                        rankItem = new RankItem(itemUser.LoginName);
                                        rankItem.Vote = 0;
                                        rankItem.LastVotingTime = DateTime.MinValue;
                                        rankItem.Location = GetTextFieldValue(Define.DATACOLUMN_LOCATION, item);
                                        rankItem.UserName = GetTextFieldValue(Define.COLUMN_TITLE, item);
                                        rankItem.IsCandidate = GetChoiceFieldValue(Define.COLUMN_ISCANDIDATE, item) == true ? 1 : 0;
                                        _pollList.Add(rankItem);
                                    }
                                    else
                                    {
                                        rankItem.Location = GetTextFieldValue(Define.DATACOLUMN_LOCATION, item);
                                        rankItem.UserName = GetTextFieldValue(Define.COLUMN_TITLE, item);
                                        rankItem.IsCandidate = GetChoiceFieldValue(Define.COLUMN_ISCANDIDATE, item) == true ? 1 : 0;
                                    }

                                }
                                string voteStr = item[Define.COLUMN_VOTE] != null ? item[Define.COLUMN_VOTE].ToString() : string.Empty;
                                string[] voteInfos = voteStr.Trim().Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
                                foreach (string userRow in voteInfos)
                                {
                                    try
                                    {
                                        string[] userInfos = userRow.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                                        string accountName = userInfos[0];
                                        string dateTimeStr = userInfos[1];

                                        RankItem rank = _pollList.Find(
                                            delegate(RankItem rk)
                                            {
                                                return rk.AccountName == accountName;
                                            });

                                        if (rank == null)
                                        {
                                            rank = new RankItem(accountName);
                                            rank.Vote = 1;
                                            rank.IsCandidate = 0;
                                            rank.LastVotingTime = Convert.ToDateTime(dateTimeStr);                                            
                                            _pollList.Add(rank);
                                        }
                                        else
                                        {
                                            ++rank.Vote;
                                            if (rank.LastVotingTime < Convert.ToDateTime(dateTimeStr))
                                            {
                                                rank.LastVotingTime = Convert.ToDateTime(dateTimeStr);
                                            }
                                        }
                                    }
                                    catch
                                    {
                                    }
                                }
                            }
                            catch
                            { }
                        }
                        _pollList.Sort();
                        int index = 0;
                        RankItem indexItem= _pollList.Find(
                            delegate(RankItem rk)
                            {
                                index++;
                                return rk.Vote == 0 || rk.IsCandidate == 0;
                            });
                        
                        if (index > 0 && index < _pollList.Count)
                        {
                            _pollList.RemoveRange(index - 1, _pollList.Count - index + 1);
                        }

                        for (int i = _pollList.Count; i < 10; i++)
                        {   
                            _pollList.Add(new RankItem());
                        }
                    }
                }
                return _pollList;
            }            
        }        
        /// <summary>
        /// Get user from a user field.
        /// </summary>
        /// <param name="fieldName"></param>
        /// <returns></returns>
        private SPUser GetUserFieldValue(string fieldName,SPListItem item)
        {
            SPFieldUser field = item.Fields[fieldName] as SPFieldUser;
            object o = item[fieldName];
            if (field != null && o != null)
            {
                SPFieldUserValue fieldValue = field.GetFieldValue(o.ToString()) as SPFieldUserValue;
                if (fieldValue != null)
                {
                    return fieldValue.User;
                }
            }
            return null;
        }
        private string GetTextFieldValue(string fieldName, SPListItem item)
        {
            try
            {
                return item[fieldName].ToString();
            }
            catch { }
            return string.Empty;
        }
        private bool GetChoiceFieldValue(string fieldName, SPListItem item)
        {
            try
            {
                return (bool)item[fieldName];
            }
            catch { }
            return false;
        }
        protected void Page_Load(object sender, EventArgs e)
        {
            repItems.DataSource = PollList;
            repItems.DataBind();
        }
        protected void repItems_ItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {

                Image imgMedal = (Image)e.Item.FindControl("imgMedal");
                Label lbOrder = (Label)e.Item.FindControl("lbOrder");
                HtmlTable tbName = (HtmlTable)e.Item.FindControl("tbName");
                Image imgHead = (Image)e.Item.FindControl("imgHead");
                HtmlTableCell tdHead = (HtmlTableCell)e.Item.FindControl("tdHead");
                if(string.IsNullOrEmpty(imgHead.ImageUrl))
                {
                    imgHead.Visible = false;
                }
                imgMedal.Visible = true;
                lbOrder.Visible = false;
                tbName.Style.Add(HtmlTextWriterStyle.Color, "#fe7b0f");
                tdHead.Style.Add(HtmlTextWriterStyle.VerticalAlign, "top");
                int order = e.Item.ItemIndex + 1;
                switch (order)
                {
                    case 1:
                        imgMedal.ImageUrl = @"Images\Ranking_Gold.png";
                        tbName.Attributes.Add("class", "");
                        break;
                    case 2:
                        imgMedal.ImageUrl = @"Images\Ranking_Silver.png";
                        break;
                    case 3:
                        imgMedal.ImageUrl = @"Images\Ranking_Copper.png";
                        break;
                    case 4:
                        imgMedal.ImageUrl = @"Images\Ranking_Iron.png";
                        break;
                    default:
                        imgMedal.Visible = false;
                        lbOrder.Visible = true;
                        lbOrder.Text = order.ToString();
                        tbName.Style.Add(HtmlTextWriterStyle.Color, "#515151");
                        tdHead.Style.Add(HtmlTextWriterStyle.VerticalAlign, "middle");
                        break;
                }                
            }

        }
    }
}
